package manongfanshen.waitset;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import util.ThreadUtil;

import java.util.Optional;
import java.util.stream.IntStream;

/**
 * @author ChangLiang
 * @date 2020/3/18
 */
public class MainTestV0 {

    private static final Object LOCK = new Object();

    /**
     * 1.所有的对象都会有一个wait set,用来存放调用了该对象wait方法之后进入block状态的线程
     * 2.线程被notify之后，进入到Runnable状态 不一定立即得到执行
     * 3.线程从wait set中被唤醒顺序不一定是FIFO 是任意的
     * 4.线程被唤醒后，必须重新获取锁
     */
    @Test
    @DisplayName("test: LOCK wait set")
    public void test() {

        // start 10 threads and all enter LOCK's wait set
        IntStream.rangeClosed(1, 10).forEach(i ->
                new Thread(String.valueOf(i)) {
                    @Override
                    public void run() {
                        synchronized (LOCK) {
                            try {
                                Optional.of(Thread.currentThread().getName() + " will come to wait set.").ifPresent(System.out::println);
                                LOCK.wait();
                                Optional.of(Thread.currentThread().getName() + " will leave to wait set.").ifPresent(System.out::println);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }.start()
        );

        // ensure all threads enter LOCK wait set
        ThreadUtil.sleepForMilliSeconds(1000);

        // start 10 threads to notify LOCK wait set, and arbitrarily chosen thread to be awakened
        IntStream.rangeClosed(1, 10).forEach(i ->
                {
                    synchronized (LOCK) {
                        LOCK.notify();
                        try {
                            // do not release LOCK monitor lock
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
        );
    }
}
